package com.fsnbigdata.service.impl;
import com.fsnbigdata.domain.*;
import com.fsnbigdata.domain.dto.NamingPair2;
import com.fsnbigdata.repository.*;
import com.fsnbigdata.service.api.AnimalConservationService;
import com.fsnbigdata.util.ObjectNull;
import com.fsnbigdata.vo.NewClass;
import com.querydsl.core.types.Predicate;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.roo.addon.layers.service.annotations.RooServiceImpl;
import com.fsnbigdata.service.api.AnimalConservationLocationService;
import io.springlets.data.domain.GlobalSearch;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;

/**
 * = AnimalConservationServiceImpl
 *
 * TODO Auto-generated class documentation
 *
 */
@RooServiceImpl(service = AnimalConservationService.class)
@Service
@Transactional(readOnly = true)
public class AnimalConservationServiceImpl implements AnimalConservationService {

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private AnimalConservationRepository animalConservationRepository;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private OrganismImageRepository organismImageRepository;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private AnimalConservationLocationRepository animalConservationLocationRepository;

    /**
     * TODO Auto-generated attribute documentation
     *
     */
    private AnimalConservationLocationService animalConservationLocationService;

    @Autowired
    private PlantConservationRepository plantConservationRepository;

    @Autowired
    private EndangeredSpeciesRepository endangeredSpeciesRepository;

    @Autowired
    private AnimalConservationImageRepository animalConservationImageRepository;

    /**
     * TODO Auto-generated constructor documentation
     *
     * @param animalConservationRepository
     * @param animalConservationLocationService
     */
    @Autowired
    public AnimalConservationServiceImpl(AnimalConservationRepository animalConservationRepository, OrganismImageRepository organismImageRepository, AnimalConservationLocationRepository animalConservationLocationRepository, AnimalConservationLocationService animalConservationLocationService) {
        this.animalConservationRepository = animalConservationRepository;
        this.organismImageRepository = organismImageRepository;
        this.animalConservationLocationRepository = animalConservationLocationRepository;
        this.animalConservationLocationService = animalConservationLocationService;
    }

    public OrganismImageRepository getOrganismImageRepository() {
        return organismImageRepository;
    }

    public void setOrganismImageRepository(OrganismImageRepository organismImageRepository) {
        this.organismImageRepository = organismImageRepository;
    }

    public AnimalConservationLocationRepository getAnimalConservationLocationRepository() {
        return animalConservationLocationRepository;
    }

    public void setAnimalConservationLocationRepository(AnimalConservationLocationRepository animalConservationLocationRepository) {
        this.animalConservationLocationRepository = animalConservationLocationRepository;
    }

    public PlantConservationRepository getPlantConservationRepository() {
        return plantConservationRepository;
    }

    public void setPlantConservationRepository(PlantConservationRepository plantConservationRepository) {
        this.plantConservationRepository = plantConservationRepository;
    }

    public EndangeredSpeciesRepository getEndangeredSpeciesRepository() {
        return endangeredSpeciesRepository;
    }

    public void setEndangeredSpeciesRepository(EndangeredSpeciesRepository endangeredSpeciesRepository) {
        this.endangeredSpeciesRepository = endangeredSpeciesRepository;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return AnimalConservationRepository
     */
    public AnimalConservationRepository getAnimalConservationRepository() {
        return animalConservationRepository;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param animalConservationRepository
     */
    public void setAnimalConservationRepository(AnimalConservationRepository animalConservationRepository) {
        this.animalConservationRepository = animalConservationRepository;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return AnimalConservationLocationService
     */
    public AnimalConservationLocationService getAnimalConservationLocationService() {
        return animalConservationLocationService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param animalConservationLocationService
     */
    public void setAnimalConservationLocationService(AnimalConservationLocationService animalConservationLocationService) {
        this.animalConservationLocationService = animalConservationLocationService;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param animalConservation
     * @param locationToAdd
     * @return AnimalConservation
     */
    @Transactional
    public AnimalConservation addToLocation(AnimalConservation animalConservation, Iterable<AnimalConservationLocation> locationToAdd) {
        animalConservation.addToLocation(locationToAdd);
        return getAnimalConservationRepository().save(animalConservation);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param animalConservation
     * @param locationToRemove
     * @return AnimalConservation
     */
    @Transactional
    public AnimalConservation removeFromLocation(AnimalConservation animalConservation, Iterable<Long> locationToRemove) {
        List<AnimalConservationLocation> location = getAnimalConservationLocationService().findAll(locationToRemove);
        animalConservation.removeFromLocation(location);
        return getAnimalConservationRepository().save(animalConservation);
    }

    @Override
    public List<NamingPair2> findAllByInitial(String initial) {
        return getAnimalConservationRepository().findAllByInitial(initial);
    }

    @Override
    public List findByType() {
        List list = new ArrayList(  );
//        List<AnimalConservation> animalConservations = getAnimalConservationRepository().findAll();
//        List<PlantConservation> plantConservations = plantConservationRepository.findAll();
//        List<EndangeredSpecies> endangeredSpecies = endangeredSpeciesRepository.findAll();
//        list.add( getList( animalConservations ) );
//        list.add( getList( plantConservations ) );
//        list.add( getList( endangeredSpecies ) );
        list.add(getAnimalConservationRepository().queryLimit());
        list.add(plantConservationRepository.queryLimit());
        list.add(endangeredSpeciesRepository.queryLimit());
        return list;
    }

    /**
     * 前台分页
     * @param condition
     * @param pageable
     * @return
     */
    @Override
    public List getPageList(String condition, String preserveLocation, Pageable pageable) {
        List list = new ArrayList(  );
        List<NewClass> animals = new ArrayList <>(  );
        List<Long> ids = new ArrayList <>(  );
        String sign = null;
        if(preserveLocation!=null&&!("".equals( preserveLocation ))){
            ids = animalConservationLocationRepository.getIds( preserveLocation );
            sign = "0";
        }
        ids = ids.size()>0?ids:null;
        list.add( animalConservationRepository.queryCountByKey(condition,sign,ids) );
        for(Object o:animalConservationRepository.queryAllByKeyAndIds(condition,sign,ids,pageable)){
            Object[] objects = (Object[]) o;
            NewClass newClass = new NewClass();
            newClass.setId( ObjectNull.takeOutNull(objects[0]) );
            newClass.setName( ObjectNull.takeOutNull(objects[1] ));
            newClass.setLatin_name( ObjectNull.takeOutNull(objects[2]));
            newClass.setCreator( ObjectNull.takeOutNull(objects[3]));
            newClass.setInitial( ObjectNull.takeOutNull(objects[4]));
            List<String> location = animalConservationLocationRepository.getLocation( ObjectNull.takeOutNull(objects[0]) );
            newClass.setLocation( location.size()>0?location.get( 0 ):null );
            List<String> url = animalConservationImageRepository.getUrl(ObjectNull.takeOutNull(objects[0]));
            newClass.setUrl( url.size()>0?url.get( 0 ):null);
            animals.add( newClass );
        }
        list.add( animals );
        return list;
    }

    /**
     * 字母索引
     * @param s
     * @return
     */
    @Override
    public List queryByAlphabet(String s) {
        //临时类
        class ChildCare{
            private Long id;
            private String name;
            private Integer sign;

            public Long getId() {
                return id;
            }

            public void setId(Long id) {
                this.id = id;
            }

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public Integer getSign() {
                return sign;
            }

            public void setSign(Integer sign) {
                this.sign = sign;
            }
        }
        List childCares = new ArrayList <>(  );
        List<Object> animalConservation =  animalConservationRepository.queryByAlphabet(s);
        List<Object> endangeredSpecies = endangeredSpeciesRepository.queryByAlphabet(s);
        List<Object> plantConservation = plantConservationRepository.queryByAlphabet(s);
        for(Integer i = 0;i<=2;i++){
            switch (i){
                case 0:
                    for(Object o:animalConservation){
                        Object[] objects1 = (Object[]) o;
                        ChildCare childCare = new ChildCare();
                        childCare.setId( Long.valueOf( ""+objects1[0] ) );
                        childCare.setName( (String)objects1[1] );
                        childCare.setSign( 0 );
                        childCares.add( childCare );
                    }
                    break;
                case 1:
                    for(Object o:plantConservation){
                        Object[] objects1 = (Object[]) o;
                        ChildCare childCare = new ChildCare();
                        childCare.setId( Long.valueOf( ""+objects1[0] ) );
                        childCare.setName( (String)objects1[1] );
                        childCare.setSign( 1 );
                        childCares.add( childCare );
                    }
                    break;
                default:
                    for(Object o:endangeredSpecies){
                        Object[] objects1 = (Object[]) o;
                        ChildCare childCare = new ChildCare();
                        childCare.setId( Long.valueOf( ""+objects1[0] ) );
                        childCare.setName( (String)objects1[1] );
                        childCare.setSign( 2 );
                        childCares.add( childCare );
                    }
                    break;
            }
        }
        return childCares;
    }

    @Override
    public List hit() {
        class Hit{
            private String name;
            private String creator;
            private Integer sign;

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public Integer getSign() {
                return sign;
            }

            public void setSign(Integer sign) {
                this.sign = sign;
            }

            public String getCreator() {
                return creator;
            }

            public void setCreator(String creator) {
                this.creator = creator;
            }
        }
        List<Hit> hits = new ArrayList <>(  );
        Pageable pageable = new PageRequest( 0,2,null );
        Page<AnimalConservation> animalConservations = animalConservationRepository.findAll( pageable );
        Page<PlantConservation> plantConservations = plantConservationRepository.findAll( pageable );
        pageable = new PageRequest( 0,1,null );
        Page<EndangeredSpecies> endangeredSpecies = endangeredSpeciesRepository.findAll( pageable );
        for(Integer i = 0;i<=2;i++){
            switch (i){
                case 0:
                    for(AnimalConservation animalConservation:animalConservations){
                        Hit hit = new Hit();
                        hit.setName( animalConservation.getName() );
                        hit.setSign( 0 );
                        hit.setCreator( animalConservation.getCreator() );
                        hits.add( hit );
                    }
                    break;
                case 1:
                    for(PlantConservation plantconservation:plantConservations){
                        Hit hit = new Hit();
                        hit.setName( plantconservation.getName() );
                        hit.setSign( 1 );
                        hit.setCreator( plantconservation.getCreator() );
                        hits.add( hit );
                    }
                    break;
                default:
                    for(EndangeredSpecies endangered:endangeredSpecies){
                        Hit hit = new Hit();
                        hit.setName( endangered.getName() );
                        hit.setSign( 2 );
                        hit.setCreator( endangered.getCreator() );
                        hits.add( hit );
                    }
                    break;
            }
        }
        return hits;
    }

    public List getList(List list){
        if(list!=null&&list.size()>4){
            return list.subList( 0,4 );
        }
        return list;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param animalConservation
     */
    @Transactional
    public void delete(AnimalConservation animalConservation) {
        // Clear bidirectional one-to-many parent relationship with AnimalConservationLocation
        for (AnimalConservationLocation item : animalConservation.getLocation()) {
            item.setAnimalConservation(null);
        }
        getAnimalConservationRepository().delete(animalConservation);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param entities
     * @return List
     */
    @Transactional
    public List<AnimalConservation> save(Iterable<AnimalConservation> entities) {
        return getAnimalConservationRepository().save(entities);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ids
     */
    @Transactional
    public void delete(Iterable<Long> ids) {
        List<AnimalConservation> toDelete = getAnimalConservationRepository().findAll(ids);
        getAnimalConservationRepository().deleteInBatch(toDelete);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param entity
     * @return AnimalConservation
     */
    @Transactional
    public AnimalConservation save(AnimalConservation entity) {
        return getAnimalConservationRepository().save(entity);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param id
     * @return AnimalConservation
     */
    public AnimalConservation findOne(Long id) {
        return getAnimalConservationRepository().findOne(id);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param id
     * @return AnimalConservation
     */
    public AnimalConservation findOneForUpdate(Long id) {
        return getAnimalConservationRepository().findOneDetached(id);
    }

    @Override
    public Page<AnimalConservation> search(Predicate predicate, Pageable pageable) {
        return getAnimalConservationRepository().findAll(predicate, pageable);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ids
     * @return List
     */
    public List<AnimalConservation> findAll(Iterable<Long> ids) {
        return getAnimalConservationRepository().findAll(ids);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return List
     */
    public List<AnimalConservation> findAll() {
        return getAnimalConservationRepository().findAll();
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return Long
     */
    public long count() {
        return getAnimalConservationRepository().count();
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param globalSearch
     * @param pageable
     * @return Page
     */
    public Page<AnimalConservation> findAll(GlobalSearch globalSearch, Pageable pageable) {
        return getAnimalConservationRepository().findAll(globalSearch, pageable, null);
    }

    @Override
    public Page<AnimalConservation> findAll(GlobalSearch globalSearch, Pageable pageable, String creator) {
        return getAnimalConservationRepository().findAll(globalSearch, pageable, creator);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @param ids
     * @param globalSearch
     * @param pageable
     * @return Page
     */
    public Page<AnimalConservation> findAllByIdsIn(List<Long> ids, GlobalSearch globalSearch, Pageable pageable) {
        return getAnimalConservationRepository().findAllByIdsIn(ids, globalSearch, pageable);
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return Class
     */
    public Class<AnimalConservation> getEntityType() {
        return AnimalConservation.class;
    }

    /**
     * TODO Auto-generated method documentation
     *
     * @return Class
     */
    public Class<Long> getIdType() {
        return Long.class;
    }
}
